

import java.util.ArrayList;

import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.AfterClass;

public class TestRockPapersScissors {
	
	public RockPaperScissors rps;
	public Player p1,p2;
	public Player p1Random,p2Random;
	
	@BeforeClass
	public void setUpClass(){
		
		ArrayList<RPSEnum> rpsListPlayer1 = new ArrayList<RPSEnum>();
		ArrayList<RPSEnum> rpsListPlayer2 = new ArrayList<RPSEnum>();
		
		rpsListPlayer1.add(RPSEnum.ROCK); //WIN
		rpsListPlayer1.add(RPSEnum.PAPER); //WIN
		rpsListPlayer1.add(RPSEnum.SCISSORS);//LOST
		rpsListPlayer1.add(RPSEnum.SCISSORS);//WIN
		rpsListPlayer1.add(RPSEnum.ROCK);//WIN
		rpsListPlayer1.add(RPSEnum.PAPER);//TIE
		
		rpsListPlayer2.add(RPSEnum.SCISSORS);//LOST
		rpsListPlayer2.add(RPSEnum.ROCK);//LOST
		rpsListPlayer2.add(RPSEnum.ROCK);//WIN
		rpsListPlayer2.add(RPSEnum.PAPER);//LOST
		rpsListPlayer2.add(RPSEnum.SCISSORS);//LOST
		rpsListPlayer2.add(RPSEnum.PAPER);//TIE
		
		
		p1= new Player("player1", rpsListPlayer1);
		p2= new Player("player2", rpsListPlayer2);
		
		p1Random= new Player("player1 Random");
		p2Random= new Player("player1 Random");
		
		rps= new RockPaperScissors();
		
	}
		
	
	
	@AfterClass
	public void tearDownClass(){
		p1=null;
		p2=null;
		p1Random=null;
		p2Random=null;
		rps=null;
	}
	
	
	
	
		////////////////Without data provider//////////////////

	
	@Test
	public void testWinPlay() {
		Assert.assertEquals(Result.WIN,rps.play(RPSEnum.PAPER, RPSEnum.ROCK));
		
	}
	
	@Test
	public void testWinPlay2() {
		
		Assert.assertEquals(Result.WIN,rps.play(RPSEnum.ROCK, RPSEnum.SCISSORS));
		
	}
	
	@Test
	public void testWinPlay3() {
		
		Assert.assertEquals(Result.WIN,rps.play(RPSEnum.SCISSORS, RPSEnum.PAPER));
		
	}
	
	@Test
	public void testTiePlay(){
		
		Assert.assertEquals(Result.TIE,rps.play(RPSEnum.PAPER, RPSEnum.PAPER));
		
	}
	
	@Test
	public void testTiePlay2(){
		
		Assert.assertEquals(Result.TIE,rps.play(RPSEnum.ROCK, RPSEnum.ROCK));
		
	}
	
	@Test
	public void testTiePlay3(){
		
		Assert.assertEquals(Result.TIE,rps.play(RPSEnum.SCISSORS, RPSEnum.SCISSORS));
		
	}
	
	
	@Test
	public void testLostPlay(){
		
		Assert.assertEquals(Result.LOST,rps.play(RPSEnum.ROCK, RPSEnum.PAPER));
		
	}
	
	@Test
	public void testLostPlay2(){
		
		Assert.assertEquals(Result.LOST,rps.play(RPSEnum.SCISSORS, RPSEnum.ROCK));
		
	}
	
	@Test
	public void testLostPlay3(){
		
		Assert.assertEquals(Result.LOST,rps.play(RPSEnum.PAPER, RPSEnum.SCISSORS));
		
	}
	
	
		///////////////With data provider//////////////////
	
	
	@Test (dataProvider = "testWin")
	public void testWinPlayDP(RPSEnum p1,RPSEnum p2) {
		
		Assert.assertEquals(Result.WIN,rps.play(p1,p2));
		
	}
	
	@Test (dataProvider = "testLost")
	public void testLostPlayDP(RPSEnum p1,RPSEnum p2) {
		
		Assert.assertEquals(Result.LOST,rps.play(p1,p2));
		
	}
	
	@Test (dataProvider = "testTie")
	public void testTiePlayDP(RPSEnum p1,RPSEnum p2) {
		
		Assert.assertEquals(Result.TIE,rps.play(p1,p2));
		
	}
	
	@DataProvider(name = "testTie")
	public Object[][] createTieData() {
	 return new Object[][] {
	   { RPSEnum.ROCK, RPSEnum.ROCK },
	   { RPSEnum.PAPER, RPSEnum.PAPER},
	   { RPSEnum.SCISSORS, RPSEnum.SCISSORS}
	 };
	}
	
	@DataProvider(name = "testWin")
	public Object[][] createLostData() {
	 return new Object[][] {
	   { RPSEnum.ROCK, RPSEnum.SCISSORS },
	   { RPSEnum.PAPER, RPSEnum.ROCK},
	   { RPSEnum.SCISSORS, RPSEnum.PAPER}
	 };
	}
	
	@DataProvider(name = "testLost")
	public Object[][] createWinData() {
	 return new Object[][] {
	   { RPSEnum.SCISSORS, RPSEnum.ROCK },
	   { RPSEnum.ROCK, RPSEnum.PAPER},
	   { RPSEnum.PAPER, RPSEnum.SCISSORS}
	 };
	}
	
	
		//////////////With determined players' moves////////////
	  @Test
	  public void testGetterName() {
		  
		  Assert.assertEquals(p2.getName(),"player2");
		  
	  }
	  
	  @Test
	  public void testGetterNbMoves(){
		  
		  Assert.assertEquals(p2.getNbMoves(),6);
		  
	  }
	  
	  @Test
	  public void testWinPlayPlayers() {
		  
		  Assert.assertEquals(rps.play(p1, p2),Result.WIN);
		  
	  }
	  
	  @Test
	  public void testLostPlayPlayers() {
		  
		  Assert.assertEquals(rps.play(p2, p1),Result.LOST);
		  
	  }
	  
	  @Test
	  public void testTiePlayPlayers() {
		  
		  Assert.assertEquals(rps.play(p1, p1),Result.TIE);
		  
	  }
	  
	  @Test
	  public void testTiePlayPlayers2() {
		  
		  Assert.assertEquals(rps.play(p2, p2),Result.TIE);
		  
	  }
	  

	  
	  
	  
		//////////////With random players' moves////////////
	  @Test
	  public void testGetterNameRandom() {
		  
		  Assert.assertEquals(p1Random.getName(),"player1 Random");
		  
	  }
	  
	  @Test
	  public void testGetterNbMovesRandom(){
		  
		  Assert.assertEquals(p1Random.getNbMoves(),10);
		  
	  }
	  
	  
	  @Test
	  public void testTiePlayRandom() {
		  
		  Assert.assertEquals(rps.play(p1Random, p1Random),Result.TIE);
	  }
	  
	  @Test
	  public void testTiePlayRandom2() {
		  
		  Assert.assertEquals(rps.play(p2Random, p2Random),Result.TIE);
	  }
	
	
	  	//////////////Tests Enums///////////////////////////
		@Test
		public void testResultEnum() {
			Assert.assertEquals(Result.WIN,Result.valueOf("WIN"));	
		}
		
		@Test
		public void testResultEnum1(){
			Assert.assertEquals(Result.LOST,Result.valueOf("LOST"));
		}
		
		@Test
		public void testResultEnum2(){
			Assert.assertEquals(Result.TIE,Result.valueOf("TIE"));
		}
		
		@Test
		public void testRPSEnum() {
			Assert.assertEquals(RPSEnum.ROCK,RPSEnum.valueOf("ROCK"));	
		}
		
		@Test
		public void testRPSEnum1(){
			Assert.assertEquals(RPSEnum.PAPER,RPSEnum.valueOf("PAPER"));
		}
		
		@Test
		public void testRPSEnum2(){
			Assert.assertEquals(RPSEnum.SCISSORS,RPSEnum.valueOf("SCISSORS"));
		}
	  
}
